package com.qq.多线程.线程同步.Lock锁;

/*
	Lock锁：
	为了更清晰的表达如何加锁和释放锁，JDK5以后提供了一个新的锁对象Lock，更加灵活、方便。
	Lock实现提供比使用synchronized方法和语句可以获得更广泛的锁定操作。
	Lock是接口不能直接实例化，这里采用它的实现类ReentrantLock来构建Lock锁对象。
	lock锁还有很多强大功能，比如抢占锁，或等待多少时间释放锁

	 构造方法：
	public ReentrantLock​()		获得Lock锁的实现类对象
	public ReentrantLock​(true)	加true获取公平锁，等待的线程会排队，先到先得

	Lock的API：
	void lock()		获得锁
	void unlock()	释放锁
	
	注：unlock()释放锁的代码一定要放在finally代码块里
	这样无论上面代码有没有出现异常，都会释放锁，不会造成死锁
	同步代码块和同步方法会自动释放锁
	
	lock锁的并发优势：
	当有几个实例方法时，可以再创建几个锁对象，这样几个方法可以并发执行，而同步代码块和同步方法不行  
  	相当于 取钱的操作 和 删除用户的操作，虽然都有线程安全问题，但可以同时进行，没必要共用一把锁。
  	注意：实例方法在同一个线程的run方法里顺序调用，没办法做到并发，要在两个不同的线程的run方法才能做到并发
	
	总结：
	lock锁可以在账户（共享资源）里创建锁对象，需要用共享资源当锁时直接调用账户的锁对象就行，
	不像同步方法必须用this作为锁对象
	 所以它可以直接在其他类里完成代码上锁解锁功能，不要求一定要面向对象设计程序，方法创建在作为共享资源的类里

*/

public class Thread_Test {
    public static void main(String[] args) {
        // 测试线程安全问题
        // 1、创建一个共享的账户对象。
        Account2 acc = new Account2("ICBC-111" , 100000);
        // 2、创建2个线程对象，操作同一个账户对象
        new OtherThread2(acc, "小明").start();
        new OtherThread2(acc,"小红").start();
        new DrawThread(acc, "小明").start();
        new DrawThread(acc,"小红").start();


    }
}